package futbol.tacticas.concursantes2007.jatiq;

import futbol.General;

import futbol.tacticas.Comando;
import futbol.tacticas.ComandoGolpearBola;
import futbol.tacticas.ComandoIrA;
import futbol.tacticas.SituacionJugadores;
import futbol.tacticas.concursantes.Tactica;

import java.awt.Color;
import java.awt.Point;

import java.util.Vector;

public class HgsATIQ_Tactica implements Tactica {

    private Vector<Comando> com;
    private Point bola;
    private SituacionJugadores sj;
    
    private Point[] mio;
    private Point[] rival;
    private int mjc;
    
    private int[][] punto = {
        {-150,0,    -150,0,     -140,0,     4},
        {-115,0,    -130,0,     -90,0,      6},
        {-95,60,    -120,20,    -75,70,     5},
        {-95,-60,   -120,-20,   -75,-70,    5},
        {-40,-85,   -90,-70,    20,-60,     6},
        {-50,0,     -70,0,      0,0,        5},
        {-40,85,    -90,70,     20,60,      6},
        {70,70,     -30,40,     120,45,     6},
        {70,-70,    -30,-40,    120,-45,    6},
        {40,0,      30,60,      75,0,       6},
        {100,0,     30,-60,     120,0,      6}
    };
    private boolean[] marca = {true,false,false,false,false,false,false,false,false,false,false};
    private Object[][] marcado = {
        {true, 0},
        {false, 0},
        {false, 0},
        {false, 0},
        {false, 0},
        {false, 0},
        {false, 0},
        {false, 0},
        {false, 0},
        {false, 0},
        {false, 0}
    };
    private double[][] factorX = {
        {1d/24d,    1d/24d,     0,          1d/12d},
        {5d/24d,    5d/24d,     1d/24d,     5d/24d},
        {1d/4d,     0,          7d/24d,     1d/6d},
        {0,         1d/4d,      7d/24d,     1d/6d},
        {1d/2d,     1d/4d,      5d/12d,     1d/2d},
        {3d/8d,     3d/8d,      3d/8d,      3d/8d},
        {1d/4d,     1d/2d,      5d/12d,     1d/2d},
        {1d/4d,     1d/4d,      5d/6d,      5d/12d},
        {1d/4d,     1d/4d,      5d/6d,      5d/12d},
        {1d/4d,     1d/4d,      1d/12d,     7d/24d},
        {1d/4d,     1d/4d,      7d/12d,     1d/6d}
    };
    private double[][] factorY = {
        {-1d/7d,    -1d/7d,      0},
        {1d/4d,     1d/4d,     1d/6d},
        {1d/4d,     1d/6d,     1d/6d},
        {1d/4d,     1d/6d,     1d/6d},
        {1d/4d,     5d/24d,    1d/3d},
        {1d/3d,     1d/3d,     1d/3d},
        {1d/4d,     5d/24d,    1d/3d},
        {1d/4d,     1d/4d,     5d/24d},
        {1d/4d,     1d/4d,     5d/24d},
        {1d/3d,     1d/3d,     1d/3d},
        {1d/3d,     1d/3d,     1d/4d}
    };
    
    public String getNombre() {
        return "JAtiq";
    }

    public Color getColor1() {
        return Color.BLACK;
    }

    public Color getColor2() {
        return Color.BLACK;
    }

    public Color getColorNumero() {
        return Color.RED;
    }

    public int getFuerza(int n) {
        return punto[n][6];
    }

    public int getXInicial(int n) {
        if(n < 4)
            return punto[n][2];
        return punto[n][0];
    }

    public int getYInicial(int n) {
        if(n < 4)
            return punto[n][3];
        return punto[n][1];
    }
    
    private int[] getCercanos(double x, double y){
        int[] mjc = new int[9];
        int sx = 1, sy = -1, t = 0;
        for(int i = 0; i < 9; i++){
            t = (i == 0 ? 2 : i);
            mjc[i] = sj.getMiJugadorMasCerca(x, y);
            if(42 % t == 0 && 42 / t != 42){
                y += 15*sy;
                if(i % 3 == 0)
                    sx = -sx;
            }
            else{
                x += 15*sx;
                if(i == 1 || i == 4)
                    sy = -sy;
            }
        }
        return mjc;
    }
    
    private int getMejorJugador(int[] mj){
        for(int i = 0; i < 9; i++)
            if(!marca[mj[i]] && mj[i] != 0)
                return mj[i];
        return -1;
    }
    
    private Point getMejorPunto(double x, double y){
        double xb = bola.getX(), yb = bola.getY();
        Point p = new Point();
        if(xb < x)
            x -= 15;
        else if(xb > x)
            x += 15;
        if(yb < y)
            y -= 15;
        else if(yb > y)
            x += 15;
        p.setLocation(x, y);
        return p;
    }
    
    private void marcar(){
        double x = 0, y = 0;
        int mj = 0;
        Point p = null;
        for(int i = 10; i > 0; i--){
            x = rival[i].getX();
            y = rival[i].getY();
            if(!Boolean.parseBoolean(marcado[i][0].toString())){
                mj = getMejorJugador(getCercanos(x, y));
                if(mj != -1){
                    p = getMejorPunto(x, y);
                    x = p.getX();
                    y = p.getY();
                    irA(mj, x, y);
                    marca[mj] = true;
                    marcado[i][0] = true;
                    marcado[i][1] = mj;
                }
            }
            else{
                p = getMejorPunto(x, y);
                x = p.getX();
                y = p.getY();
                irA(Integer.parseInt(marcado[i][1].toString()), x, y);
            }
        }
    }
    
    private int getMasLibre(Vector<Integer> mjp){
        double xmj = 0, ymj = 0, xjc = 0, yjc = 0, d = 0;
        int mj = 0, jc = 0;
        while(!mjp.isEmpty()){
            mj = mjp.remove(0);
            jc = sj.getContrarioMasCerca(mj);
            xmj = mio[mj].getX();
            ymj = mio[mj].getY();
            xjc = rival[jc].getX();
            yjc = rival[jc].getY();
            d = General.getDistancia(xmj, ymj, xjc, yjc);
            if(d > 20)
                return mj;
        }
        return -1;
    }
    
    private Vector<Integer> getPosibles(int mj){
        Vector<Integer> mjp = new Vector<Integer>();
        double xmj = mio[mj].getX(), xt = 0;
        for(int i = 1; i < 11; i++)
            if(i != mj){
                xt = mio[i].getX();
                if(xt >= xmj+30)
                    mjp.add(i);
            }
        return mjp;
    }
    
    private void moverBalon(int mj){
        for(int i = 10; i > 0; i--){
            marca[mj] = false;
            marcado[mj][0]=false;
        }
        double xmj = mio[mj].getX(), ymj = mio[mj].getY(), x = 0, y = 0, xjc = 0, yjc = 0;
        int jr = 0;
        Vector<Integer> mjp = null;
        if(mj == 0){
            mjp = new Vector<Integer>();
            mjp.add(9);
            mjp.add(10);
            jr = getMasLibre(mjp);
            if(jr != -1){
                x = mio[jr].getX();
                y = mio[jr].getY();
            }
            else{
                x = 180;
                y = 0;
            }
        }
        else if(bola.getX() < 40){
            int jc = sj.getContrarioMasCerca(mj);
            xjc = rival[jc].getX();
            yjc = rival[jc].getY();
            double d = General.getDistancia(xmj, ymj, xjc, yjc);
            if(d <= 50 || xmj >= punto[mj][4]){
                mjp = getPosibles(mj);
                jr = getMasLibre(mjp);
                if(jr != -1){
                    x = mio[jr].getX();
                    y = mio[jr].getY();
                }
                else{
                    x = 180;
                    y = 0;
                }
            }
            else{
                x = xmj + 15;
                if(punto[mj][1] < 0)
                    y = ymj - 15;
                else if(punto[mj][1] == 0){
                    x = xmj + 20;
                    y = ymj;
                }
                else
                    y = ymj + 7;
            }
        }
        else{
            x = 180;
            y = 0;
        }
        com.add(new ComandoGolpearBola(mj, x, y));
    }
    
    private void irA(int mj, double x, double y){
        com.add(new ComandoIrA(mj, x, y));
    }
    
    private void movimientoDe(int mj){
        double x = 0, y = 0;
        double xb = bola.getX(), yb = bola.getY();
        if(mj == mjc){
            irA(mj, xb, yb);
            moverBalon(mj);
        }
        else{
            if(xb < 0){
                if(xb < -40){
                    x = punto[mj][2];
                    if(yb < 0){
                        y = punto[mj][3] - 120*factorY[mj][0];
                        if(mj != 2){
                            x += (xb + 40)*factorX[mj][0];
                            if(yb > y)
                                y = punto[mj][3] + yb*factorY[mj][0];
                        }
                        if(mj == 0)
                            y += 5d*(xb + 40)/12d + yb*1d/12d;
                    }
                    else{
                        y = punto[mj][3] + 120*factorY[mj][0];
                        if(mj != 3){
                            x += (xb + 40)*factorX[mj][1];
                            if(yb < y)
                                y = punto[mj][3] + yb*factorY[mj][0];
                        }
                        if(mj == 0)
                            y -= 5d*(xb + 40)/12 - yb*1d/12d;
                    }
                }
                else{
                    x = punto[mj][0] + xb*factorX[mj][2];
                    double ff = (factorY[mj][1]*(40 + xb) - factorY[mj][0]*xb)/40d;
                    y = punto[mj][1] +yb*ff;
                }
            }
            else{
                if(xb <= 40){
                    x = punto[mj][0] + xb*factorX[mj][3];
                    double ff = (factorY[mj][1]*(40 - xb) + factorY[mj][2]*xb)/40d;
                    y = punto[mj][1] + yb*ff;
                }
                else{
                    x = punto[mj][4];
                    y = punto[mj][5] + yb*factorY[mj][2];
                }
            }
            irA(mj, x, y);
        }
    }
    
    private void moverPortero(){
        int x = (int)bola.getX();
        if(x < -10){
            int y = (int)(bola.getY()/2);
            if (y < -25) y = -25;
            if (y > 25) y = 25;
            com.add(new ComandoIrA(0, getXInicial(0), y));
        }
        else
            com.add(new ComandoIrA(0, getXInicial(0), getYInicial(0)));
        if(mjc == 0)
            moverBalon(0);
    }

    public Vector<Comando> getComandos(SituacionJugadores sju) {
        sj = sju;
        com = new Vector<Comando>();
        bola = sj.getBola();
        mio = sj.getMisJugadores();
        rival = sj.getContrario();
        mjc = sj.getMasCercanoDeBola();
        
        for(int i = 0; i < 11; i++)
            movimientoDe(i);
        if(!sj.estoyMasCercaDeBola())
            marcar();
        moverPortero();
        com.add(new ComandoIrA(mjc,bola.getX(), bola.getY()));
        
        return com;
    }
}